/*******************************************************************************
   @file    dev_gpio.h
   @author  H.M.Shim (elecage@gmail.com)
   @version 
   @date    2013. 7. 25.
   @brief   GPIO의 디바이스 드라이버 정의
  ******************************************************************************
  The MIT License (MIT)

Copyright (c) 2013 <copyright holders>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
  ******************************************************************************
  */



/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef DEV_GPIO_H_
#define DEV_GPIO_H_

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include "devio.h"
#include "stm32f4xx_gpio.h"

/* Exported typedef ----------------------------------------------------------*/
/**
 * @struct Dev_Gpio_flag
 * @brief GPIO의 상태 플래그 구조체
 */
typedef struct {
	int8_t 	stat;				/**< @brief 장치의 상태 플래그 */
	int8_t	rdwr[16];			/**< @brief 각 핀별로 입출력 여부를 표시 */
	int8_t  readInOut;			/**< @brieff 각 핀을 읽을 때 입력 레지스터를 읽일지 출력 레지스터를 읽을지 결정 */
}Dev_Gpio_flag;

/**
 * @struct EXTI_Config
 * @brief 외부 인터럽트를 사용할 경우의 설정 구조체
 * 외부인터럽트를 사용할 핀에 대해 설정한다.
 */
typedef struct {
	uint8_t					pinsource;	/**< @brief 외부 인터럽트로 사용할 핀 소스 */
	EXTIMode_TypeDef 		mode;		/**< @brief 외부 인터럽트 모드 */
	EXTITrigger_TypeDef 	trigger;	/**< @brief 인터럽트의 트리거 방법 */
	uint8_t					priority;	/**< @brief 인터럽트의 주 우선순위 */
	uint8_t					subPriority;/**< @brief 인터럽트의 부 우선순위 */
	InterruptHandleFunc		func;		/**< @brief 인터럽트가 발생할 때의 인터럽트 핸들러 함수의 포인터 */
}EXTI_Config;
/* Exported constants --------------------------------------------------------*/
/**
 * @enum Dev_GPIO_IOCTL_Param
 * @brief GPIO의 devIoctl() 함수의 require 인자에 들어가는 설정 변수의 enumeration
 */
enum Dev_GPIO_IOCTL_Param {
	DEV_GPIO_SET_BIT,					/**< @brief 해당하는 GPIO 비트를 1로 설정한다. */
	DEV_GPIO_CLEAR_BIT,					/**< @brief 해당하는 GPIO 비트를 0으로 설정한다. */
	DEV_GPIO_TOGGLE_BIT,				/**< @brief 해당하는 GPIO 비트갸 0이면 1로, 1이면 0으로 설정한다. */
	DEV_GPIO_GET_INPUT_BIT,				/**< @brief 해당 비트의 입력 레지스터 값을 읽어온다. */
	DEV_GPIO_GET_OUTPUT_BIT,			/**< @brief 해당 비트의 출력 레지스터 값을 읽어온다. */
	DEV_GPIO_CONFIG_BIT,				/**< @brief 해당 비트를 설정한다. */
	DEV_GPIO_CONFIG_INTERRUPT,			/**< @brief 외부 인터럽트를 설정한다. */
};

#define READ_INPUT		1				/**< @brief Dev_Gpio_flag.readInOut을 입력으로 설정 */
#define READ_OUTPUT		0				/**< @brief Dev_Gpio_flag.readInOut을 출력으로 설정 */

/* Exported macro ------------------------------------------------------------*/

/* Exported variables ------------------------------------------------------- */
extern InterruptHandleFunc extiIsrFunc[16];
/* Exported functions ------------------------------------------------------- */
int32_t registerDev_Gpio(void);
int32_t dev_GpioInit(int32_t dd);
int32_t dev_GpioOpen(const int8_t* devname, int32_t flags);
ssize_t dev_GpioWrite(int32_t dd, const void *buf, size_t n);
ssize_t	dev_GpioRead(int32_t dd, void *buf, size_t nbytes);
ssize_t dev_GpioIoctl(int32_t dd, int32_t request, void* data);
int32_t dev_GpioClose(int32_t dd);

void dev_GpioConfigEXTI(uint8_t portsource, EXTI_Config* config);

#ifdef USE_CMDLINE
int32_t dev_GpioInitCmd(int32_t argc, int8_t *argv[]);
int32_t dev_GpioOpenCmd(int32_t argc, int8_t *argv[]);
int32_t dev_GpioReadCmd(int32_t argc, int8_t *argv[]);
int32_t dev_GpioWriteCmd(int32_t argc, int8_t *argv[]);
int32_t dev_GpioIoctlCmd(int32_t argc, int8_t *argv[]);
int32_t dev_GpioCloseCmd(int32_t argc, int8_t *argv[]);
#endif /* USE_CMDLIN */
#endif /* DEV_GPIO_H_ */
